package com.nervenets.general.i18n;


import com.nervenets.general.entity.MatchedResult;
import com.nervenets.general.utils.MatchedUtil;
import com.nervenets.general.utils.PropertiesLoader;
import com.nervenets.general.utils.SpringContextHolder;
import com.nervenets.general.utils.StringUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;

import java.util.Locale;

public class I18nTranslator {
    private static MessageSource messageSource;

    private static MessageSource getMessageSource() {
        if (null == messageSource) {
            messageSource = SpringContextHolder.getBean(MessageSource.class);
        }
        return messageSource;
    }

    public static String translate(Enum enumType) {
        return translate(enumType, enumType.name());
    }

    public static String translate(Enum enumType, String defaultValue) {
        String enumCode = resolveEnumCode(enumType);
        return getMessage(enumCode, defaultValue);
    }

    public static String translate(String code) {
        return getMessage(code, code + "." + LocaleResolver.resolveLocale());
    }

    public static String translate(String code, String defaultValue) {
        return getMessage(code, defaultValue);
    }

    public static String braceTranslate(String value) {
        final MatchedResult<String> matchedResult = MatchedUtil.isPropertiesCode(value);
        return matchedResult.isMatched() ? translate(matchedResult.getResult(), value) : value;
    }

    private static String resolveEnumCode(Enum enumType) {
        String clazzName = enumType.getClass().getName();
        String packName = enumType.getClass().getPackage().getName();
        clazzName = clazzName.replace(packName, "enum").toLowerCase();
        return clazzName + "." + enumType.toString().toLowerCase();
    }

    private static String getMessage(String code, String defaultValue) {
        final Locale locale = LocaleResolver.resolveLocale();
        try {
            String property = getMessageSource().getMessage(code, null, locale);
            return StringUtils.isEmpty(property) ? defaultValue : property;
        } catch (NoSuchMessageException e) {
            final PropertiesLoader loader = new PropertiesLoader(String.format("source_messages_%s.properties", locale));
            String property = loader.getProperty(code);
            return StringUtils.isEmpty(property) ? defaultValue : property;
        }
    }
}
